<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>集合-Set</title>
</head>

<body>
    <script>
        // 集合是由一组无序且唯一(即不能重复)的项组成的; 你也可以把集合想象成一个既没有重复元素，也没有顺序概念的数组。
        // add(value):向集合添加一个新的项。
        // delete(value):从集合移除一个值。
        // has(value):如果值在集合中，返回true，否则返回false。
        // clear():移除集合中的所有项。
        // size():返回集合所包含元素的数量。与数组的length属性类似。 
        // values():返回一个包含集合中所有值的数组。



        // 并集:对于给定的两个集合，返回一个包含两个集合中所有元素的新集合。(合并A和B)
        // 交集:对于给定的两个集合，返回一个包含两个集合中共有元素的新集合。(同时存在A和B中)
        // 差集:对于给定的两个集合，返回一个包含所有存在于第一个集合且不存在于第二个集合的元素的新集合。(A有, B没有; A-B)
        // 子集:验证一个给定集合是否是另一集合的子集。(A > B)
        // 补集:设S是一个集合，A是S的一个子集，由S中所有不属于A的元素组成的集合，叫做子集A在S中的绝对补集

        // 补集就是对于一个集合A和全集B来说，A的补集就是在全集B中所有不属于A的元素。
        // 差集是对于两个集合来说的，假设两个集合A，B。A-B就是属于A但是不属于B的元素的集合。若令A交B=C，那么A-B=A-C，也可以认为是C在全集A中的补集。


        // var a = [1, 2, 3, 5, 6];
        // var b = [1, 2, 6, 7, 8];
        // // 交集
        // const aAndB = a.filter(item => b.includes(item));
        // // 并集
        // const aAddB = [...new Set(a.concat(b))]
        // // 补集
        // const aBuB = a.filter(item => !b.includes(item));
        // console.log(aAndB, aAddB, aBuB)


        var a = [
            { id: '001', name: 'zhangsan' },
            { id: '002', name: 'tom' },
            { id: '003', name: 'jack' },
            { id: '004', name: 'fei' },
            { id: '005', name: 'ming' }
        ];
        var b = [
            { id: '003', name: 'jack' },
            { id: '005', name: 'ming' },
            { id: '007', name: 'hello' },
            { id: '008', name: 'milk' },
        ];
        var c = [
            { id: '001', name: 'zhangsan' },
            { id: '002', name: 'tom' },
        ];
        var obj = {};
        var arr = a.concat(b);
        // 交集：定义一个对象，通过其属性值是否出现多次判断交集
        let demo1 = arr.reduce(function (pre, cur) {
            obj.hasOwnProperty(cur.id) ? pre.push(cur) : obj[cur.id] = true;
            return pre;
        }, []);
        // 并集：每次遍历将还未出现的项进行收集
        let demo2 = arr.reduce(function (pre, cur) {
            if (!obj.hasOwnProperty(cur.id)) {
                pre.push(cur);
            }
            obj[cur.id] = true;
            return pre;
        }, [])
        //补集:a中每一项都不在b中 (A有B没有)
        let demo3 = a.reduce(function (pre, cur) {
            if (b.every(item => item.id !== cur.id)) {
                pre.push(cur)
            }
            return pre;
        }, [])

        // 差集 (A-B)
        let demo4 = a.reduce(function (pre, cur) {
            if (c.every(item => item.id !== cur.id)) {
                pre.push(cur)
            }
            return pre;
        }, [])
        console.log(arr, demo1, demo2, demo3, demo4)
    </script>
</body>

</html>